home *** CD-ROM | disk | FTP | other *** search
/ Carousel / CAROUSEL.cdr / mactosh / code / p_serlib.sit / Serial Library Source Code / serial.readTilStr.dll.c < prev    next >
C/C++ Source or Header  |  1989-07-27  |  9KB  |  317 lines

  1. /***********************************************************************/
  2. /*    
  3. /*    serial.readTilStr.dll.c
  4. /*    by Atul Butte
  5. /*    Copyright ⌐ 1989 by Microsoft Corporation
  6. /*    All Rights Reserved
  7. /*
  8. /*    version 1.0
  9. /*    
  10. /*    
  11. /*    This CALL/REGISTER will read from the serial port until the specifed
  12. /*    string is read up to 255 characters. The characters are stored in
  13. /*    a string and are returned.
  14. /*    
  15. /*    Excel usage:
  16. /*    
  17. /*    = Register( "serial library", "serial.readTilStr", "GHDJCG" )
  18. /*    = Call( ref, portNumber, matchStr, maxTime, readConfigStr, )
  19. /*    
  20. /*    where
  21. /*        portNumber        = number of port (1 = modem, 2 = printer)
  22. /*        matchStr        = keep reading until we read this string
  23. /*        maxTime            = maximum amount of time to wait for characters
  24. /*                          in 1/60 second units
  25. /*        readConfigStr    = configuration of communications protocol, etc
  26. /*
  27. /*    The extra comma at the end of the CALL parameter list must be present.
  28. /*    
  29. /***********************************************************************/
  30.  
  31. /***********************************************************************/
  32. /*
  33. /*    D E F I N E S
  34. /*
  35. /***********************************************************************/
  36.  
  37. #define ROUTINE_NAME    "serial.readTilStr"
  38. #define hNIL 0L
  39. #define pNIL 0L
  40.  
  41. /***********************************************************************/
  42. /*
  43. /*    I N C L U D E S
  44. /*
  45. /***********************************************************************/
  46.  
  47. #include "serial.h"
  48. #include "error.h"
  49. #include "get_port.h"
  50. #include "interpret.h"
  51. #include "get_read_flags.h"
  52.  
  53. /***********************************************************************/
  54. /*
  55. /*    P R O T O T Y P E S
  56. /*
  57. /***********************************************************************/
  58.  
  59. void initialize_next( Ptr pnxt, char *pstMatch );
  60. char check_for_match( char ch, unsigned char cchMatched, unsigned char cMatchLength, char *pstMatch, Ptr pnxt );
  61.  
  62. /***********************************************************************/
  63. /*
  64. /*    main
  65. /*
  66. /***********************************************************************/
  67.  
  68. pascal char *main( port, pstMatch, timeDur, pszConfig, pstBuff )
  69.  
  70.     unsigned short            port;                    /* serial port to use */
  71.     char                    *pstMatch;                /* keep reading until we read this string */
  72.     unsigned long            timeDur;                /* maximum time to wait for chars (in ticks) */
  73.     char                    *pszConfig;                /* communications configuration string */
  74.     char                    *pstBuff;                /* buffer in which to return string */
  75.     
  76. {
  77.     register OSErr            err;                    /* result code from Toolbox routines */
  78.     ParamBlockRec            param;                    /* parameter block for read/write */
  79.     
  80.     Boolean                    fEcho = false;            /* flag for echoing characters */
  81.     Boolean                    fEdit = false;            /* flag for allowing edit characters */
  82.     Boolean                    fStripLF = false;        /* flag for stripping line feeds */
  83.     Boolean                    fStrip8Bit = false;        /* flag for stripping high bit */
  84.     Boolean                    fAddLF = false;            /* flag for adding LF after CR */
  85.     Boolean                    fIgnore = false;        /* flag for ignoring escape chars */
  86.     
  87.     Handle                    hnxt;                    /* handle to the next table */
  88.     register Ptr            pnxt;                    /* pointer to the next table */
  89.     long                    cchBuff = 0;            /* number of characters waiting in read buffer */
  90.     register unsigned long    timeStop;                /* time at which to stop */
  91.     short                    refIn;                    /* reference number for input port */
  92.     short                    refOut;                    /* reference number for output port */
  93.     register char            *pst;                    /* pointer to current character in buffer */
  94.     char                    chRead;                    /* buffer used to read a character */
  95.     register char            ch;                        /* character read */
  96.     char                    echoBackspace[3];        /* characters to send to echo Backspace */
  97.     char                    echoLinefeed;            /* characters to send to echo Linefeed */
  98.     register unsigned char    cchMatched;                /* number of characters matching so far */
  99.     register unsigned char    cchMatch;                /* number of characters to match */
  100.     
  101.     register unsigned char    cch = 0;
  102.     
  103.     RememberA0();
  104.     SetUpA4();
  105.     
  106.     if( pstBuff == pNIL ) {
  107.         display_error( "The fifth parameter must be a pointer to an empty string buffer." );
  108.         RestoreA4( );
  109.         return( pstBuff );
  110.     }
  111.     pst = pstBuff;
  112.     *pst = 0;
  113.     pst++;
  114.     
  115.     if( pszConfig == pNIL ) {
  116.         display_error( "The fourth parameter must be a configuration string." );
  117.         RestoreA4( );
  118.         return( pstBuff );
  119.     }
  120.     if( pstMatch == pNIL ) {
  121.         display_error( "The second parameter must be a string to match." );
  122.         RestoreA4( );
  123.         return( pstBuff );
  124.     }
  125.     if( *pstMatch == 0 ) {
  126.         display_error( "You must specify a string to match with at least one character." );
  127.         RestoreA4( );
  128.         return( pstBuff );
  129.     }
  130.     
  131.     err = get_port( port, &refIn, &refOut );
  132.     if( err != noErr ) {
  133.         display_error( "Illegal port number." );
  134.         RestoreA4( );
  135.         return( pstBuff );
  136.     }
  137.     
  138.     get_read_flags( pszConfig, &fEcho, &fEdit, &fStripLF, &fStrip8Bit, &fAddLF, &fIgnore );
  139.     
  140.     if( !fIgnore ) {
  141.         err = interpret( pstMatch );
  142.         if( err != noErr ) {
  143.             RestoreA4( );
  144.             return( pstBuff );
  145.         }
  146.     }
  147.  
  148.     cchMatched = 1;
  149.     cchMatch = *pstMatch;
  150.     if( cchMatch > 1 ) {
  151.         hnxt = NewHandle( (long) *pstMatch + 1 );
  152.         HLock( hnxt );
  153.         pnxt = *hnxt;
  154.         initialize_next( pnxt, pstMatch );
  155.     }
  156.     
  157.     if( fEcho ) {
  158.         echoBackspace[0] = kchBackspace;
  159.         echoBackspace[1] = ' ';
  160.         echoBackspace[2] = kchBackspace;
  161.         if( fAddLF ) {
  162.             echoLinefeed = kchLinefeed;
  163.         }
  164.     }
  165.     
  166.     timeStop = TickCount( ) + timeDur;
  167.     
  168.     while( cch < 254 ) {
  169.         if( ( timeDur != 0 ) && ( TickCount( ) >= timeStop ) ) {
  170.             break;
  171.         }
  172.         err = SerGetBuf( refIn, &cchBuff );
  173.         if( err != noErr ) {
  174.             display_error( "Error trying to count buffer." );
  175.             break;
  176.         }
  177.         if( cchBuff == 0 )
  178.             continue;
  179.         param.ioParam.ioReqCount = 1;
  180.         param.ioParam.ioBuffer = &chRead;
  181.         param.ioParam.ioRefNum = refIn;
  182.         err = PBRead( ¶m, false );
  183.         if( err != noErr ) {
  184.             display_error( "Error reading from serial port." );
  185.             break;
  186.         }
  187.         ch = chRead;
  188.         if( ( (ch == kchBackspace) || (ch == kchDelete) ) && (fEdit) ) {
  189.             if( fEcho ) {
  190.                 param.ioParam.ioReqCount = 3;
  191.                 param.ioParam.ioRefNum = refOut;
  192.                 param.ioParam.ioBuffer = echoBackspace;
  193.                 err = PBWrite( ¶m, false );
  194.                 if( err != noErr ) {
  195.                     display_error( "Error echoing backspace to serial port." );
  196.                     break;
  197.                 }
  198.             }
  199.         } else if( fEcho ) {
  200.             param.ioParam.ioReqCount = 1;
  201.             param.ioParam.ioRefNum = refOut;
  202.             param.ioParam.ioBuffer = &chRead;
  203.             err = PBWrite( ¶m, false );
  204.             if( err != noErr ) {
  205.                 display_error( "Error echoing to serial port." );
  206.                 break;
  207.             }
  208.             if( (ch == kchReturn) && (fAddLF) ) {
  209.                 param.ioParam.ioReqCount = 1;
  210.                 param.ioParam.ioRefNum = refOut;
  211.                 param.ioParam.ioBuffer = &echoLinefeed;
  212.                 err = PBWrite( ¶m, false );
  213.                 if( err != noErr ) {
  214.                     display_error( "Error echoing linefeed to serial port." );
  215.                     break;
  216.                 }
  217.             }
  218.         }
  219.         if( fStrip8Bit ) {
  220.             ch &= 0x7F;
  221.         }
  222.         if( ( (ch == kchBackspace) || (ch == kchDelete) ) && (fEdit) ) {
  223.             cch--;
  224.             if( cch >= 0 ) {
  225.                 pst--;
  226.             } else {
  227.                 cch = 0;
  228.             }
  229.         } else if( (ch == kchLinefeed) && (fStripLF) ) {
  230.         } else {
  231.             *pst = ch;
  232.             pst++;
  233.             cch++;
  234.         }
  235.         
  236.         if( (ch == kchLinefeed) && (fStripLF) ) {
  237.         } else {
  238.             cchMatched = check_for_match( ch, cchMatched, cchMatch, pstMatch, pnxt );
  239.             if( cchMatched > cchMatch ) /* if we found a match */
  240.                 break;
  241.         }
  242.     }
  243.     
  244.     if( cchMatch > 1 )
  245.         DisposHandle( hnxt );
  246.     *pstBuff = cch;
  247.     RestoreA4()
  248.     return( pstBuff );
  249. }
  250.  
  251. /***********************************************************************/
  252. /*
  253. /*    initialize_next
  254. /*
  255. /***********************************************************************/
  256.  
  257. void initialize_next( pnxt, pstMatch )
  258.  
  259.     register Ptr            pnxt;                    /* pointer to the next table */
  260.     char                    *pstMatch;                /* keep reading until we read this string */
  261.     
  262. {
  263.     register unsigned long    i = 1, j = 0;            /* index through match string */
  264.     register unsigned char    cchMatch = *pstMatch;    /* number of characters to match */
  265.     
  266.     pnxt[1] = 0;
  267.     do {
  268.         if( ( j == 0 ) || ( pstMatch[i] == pstMatch[j] ) ) {
  269.             i++;
  270.             j++;
  271.             pnxt[i] = j;
  272.         } else {
  273.             j = pnxt[j];
  274.         }
  275.     } while( i <= cchMatch );
  276. }
  277.  
  278. /***********************************************************************/
  279. /*
  280. /*    check_for_match
  281. /*
  282. /***********************************************************************/
  283.  
  284. char check_for_match( ch, cchMatched, cchMatch, pstMatch, pnxt )
  285.  
  286.     register char            ch;                        /* character read */
  287.     register unsigned char    cchMatched;                /* number of characters matching so far */
  288.     register unsigned char    cchMatch;                /* number of characters to match */
  289.     char                    *pstMatch;                /* keep reading until we read this string */
  290.     register Ptr            pnxt;                    /* pointer to the next table */
  291.     
  292. {
  293.     if( cchMatch == 1 ) {
  294.         if( ch == pstMatch[1] ) {
  295.             return( 2 );
  296.         } else {
  297.             return( 1 );
  298.         }
  299.     } else {
  300.         do {
  301.             if( ( cchMatched == 0 ) || ( ch == pstMatch[cchMatched] ) ) {
  302.                 cchMatched++;
  303.                 break;
  304.             } else {
  305.                 cchMatched = pnxt[cchMatched];
  306.             }
  307.         } while( cchMatched <= cchMatch );
  308.         
  309.         return( cchMatched );
  310.     }
  311. }
  312.  
  313. #include "get_port.c"
  314. #include "interpret.c"
  315. #include "get_read_flags.c"
  316.  
  317.